package com.tcxhb.job.core.schedule.workflow;

import com.tcxhb.job.dao.dataobject.JobInfoDO;
import com.tcxhb.job.dao.dataobject.JobInstanceDO;
import com.tcxhb.job.common.constants.BaseException;
import com.tcxhb.job.common.constants.CommonErrorCode;
import com.tcxhb.job.common.model.MiscResult;
import com.tcxhb.job.core.schedule.execute.JobRunContext;
import com.tcxhb.job.core.service.job.JobInfoService;
import com.tcxhb.job.core.service.job.JobInstanceService;
import com.tcxhb.job.core.utils.SchedulerTimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @Auther: tcxhb
 * @Date: 2023/11/12
 */
@Component
@Slf4j
public class InstanceCreateFlow implements FlowHandler<JobRunContext> {
    @Autowired
    private JobInstanceService jobInstanceService;
    @Autowired
    private JobInfoService jobInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MiscResult handle(JobRunContext cxt) {
        //批量创建数据库
        List<JobInstanceDO> list = cxt.getInstanceList();
        for (JobInstanceDO instanceDO : list) {
            jobInstanceService.create(instanceDO);
        }
        // 定时触发的
        if (!cxt.getReq().getRunOnce()) {
            updateNextSchedule(cxt.getJobDO(), cxt.getReq().getScheduleTime());
        }
        cxt.setInstanceList(list);
        return MiscResult.suc();
    }

    /**
     * 刷新下一个
     *
     * @param jobDO
     * @param scheduleTime
     */
    private void updateNextSchedule(JobInfoDO jobDO, Long scheduleTime) {
        Long nextTime = SchedulerTimeUtils.nextSchedulerTime(jobDO, new Date(scheduleTime));
        Boolean result = jobInfoService.freshNextScheduleTime(jobDO, nextTime);
        if (result == false) {
            log.error("job-repeat-run,{},{}", jobDO.getId(), scheduleTime);
            throw new BaseException(CommonErrorCode.DB_OPERATE_ERROR);
        }
    }
}
